package de.backtomedieval.units;

//position @ Array
//Archer // Short // Long // 2-Hand // Spear // Halberdier // Hoplit // Ballista // Siege - Ram // Catapult // Trebuchet // Tower

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

import de.backtomedieval.game.City;
import de.backtomedieval.game.Fight;
import de.backtomedieval.research.Technology;

public class UnitGroup {
	private ArrayList<AbstractUnit> units;
	public boolean silent = false;
	private Technology technology;
	
	
	public UnitGroup(Technology technology) {
		setUnits(new ArrayList<AbstractUnit>());
		this.technology=technology;
	}

	public void clean() {
		for (int i = 0; i < getUnits().size(); i++) {
			if (!getUnits().get(i).isAlive()) {
				getUnits().remove(i);
				i--;
			}
		}
	}

	public String toString() {
		return makeUnitSet().toString();
	}

	public void addArchers(int count) {
		for (int i = 0; i < count; i++) {
			units.add(new Archer(technology));
		}
	}

	public void addShortSwordsmen(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new ShortSwordsman(technology));
		}
	}

	public void addLongSwordsmen(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new LongSwordsman(technology));
		}
	}

	public void addTwoHandedSwordman(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new TwoHandedSwordman(technology));
		}
	}

	public void addSpearman(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new Spearman(technology));
		}
	}

	public void addHalberdier(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new Halberdier(technology));
		}
	}

	public void addHoplit(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new Hoplit(technology));
		}
	}

	public void addBallista(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new Ballista(technology));
		}
	}

	public void addSiegeRam(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new SiegeRam(technology));
		}
	}

	public void addCatapult(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new Catapult(technology));
		}
	}

	public void addTrebuchet(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new Trebuchet(technology));
		}
	}

	public void addTower(int count) {
		for (int i = 0; i < count; i++) {
			getUnits().add(new Tower(technology));
		}
	}

	public int attackRound(UnitGroup enemy, int attackRound, City city) {
		enemy.attackRoundHalf(this, attackRound,null);
		if (this.getUnits().size() == 0) {
			// TODO: Kampf verloren. Keine Einheiten mehr uebrig.
			return Fight.LOOSE;
		}
		this.attackRoundHalf(enemy, attackRound,city);
		if (enemy.getUnits().size() == 0) {
			// TODO: Kampf gewonnen. Gegner hat keine Einheiten mehr.
			return Fight.WIN;
		}
		return Fight.NO_RESULT;
	}

	public int defenseRound(UnitGroup enemy, int attackRound, City city) {
		this.attackRoundHalf(enemy, attackRound,null);
		if (enemy.getUnits().size() == 0) {
			// TODO: Kampf gewonnen. Gegner hat keine Einheiten mehr.
			return Fight.WIN;
		}
		enemy.attackRoundHalf(this, attackRound,city);
		if (this.getUnits().size() == 0) {
			// TODO: Kampf verloren. Keine Einheiten mehr �brig.
			return Fight.LOOSE;
		}
		return Fight.NO_RESULT;
	}

	private void attackRoundHalf(UnitGroup enemy, int attackRound, City defendingCity) {
		Random ra = new Random();
		int attackedEnemy = 0;
		for (Iterator<AbstractUnit> iter = this.getUnits().iterator(); iter.hasNext();) {
			AbstractUnit u = iter.next();
			// Kann ueberhaupt angegriffen werden?!
			if (u.canAttack(attackRound)) {
				for (int j = 0; j < u.getAttackMultiple(); j++) {
										
					if (enemy.getUnits().size() == 0) {
						return;
					}
					attackedEnemy = ra.nextInt(enemy.getUnits().size());
					u.attack(enemy.getUnits().get(attackedEnemy),defendingCity);
					if (!enemy.getUnits().get(attackedEnemy).isAlive()) {
						enemy.getUnits().remove(attackedEnemy);
					}
				}
			}
		}
	}

	public void setUnits(ArrayList<AbstractUnit> units) {
		this.units = units;
	}

	public ArrayList<AbstractUnit> getUnits() {
		return units;
	}

	public UnitSet makeUnitSet() {
		int counter[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		int otherCount = 0;
		AbstractUnit other = null;
		for (int i = 0; i < units.size(); i++) {
			if (units.get(i) instanceof Archer) {
				counter[0]++;
			} else if (units.get(i) instanceof ShortSwordsman) {
				counter[1]++;
			} else if (units.get(i) instanceof LongSwordsman) {
				counter[2]++;
			} else if (units.get(i) instanceof TwoHandedSwordman) {
				counter[3]++;
			} else if (units.get(i) instanceof Spearman) {
				counter[4]++;
			} else if (units.get(i) instanceof Halberdier) {
				counter[5]++;
			} else if (units.get(i) instanceof Hoplit) {
				counter[6]++;
			} else if (units.get(i) instanceof Ballista) {
				counter[7]++;
			} else if (units.get(i) instanceof SiegeRam) {
				counter[8]++;
			} else if (units.get(i) instanceof Catapult) {
				counter[9]++;
			} else if (units.get(i) instanceof Trebuchet) {
				counter[10]++;
			} else if (units.get(i) instanceof Tower) {
				counter[11]++;
			} else if (units.get(i) instanceof RedDragon) {
				otherCount++;
				other = units.get(i);
			}

		}
		UnitSet u =new UnitSet(counter[0], counter[1], counter[2], counter[3],
				counter[4], counter[5], counter[6], counter[7], counter[8],
				counter[9], counter[10], counter[11],technology);
		if (otherCount!=0) {
			u.setOther(other, otherCount);
		}
		return  u;
	}

	public void addOther(AbstractUnit other, int otherCount) {
		for (int i = 0; i < otherCount; i++) {
			AbstractUnit o;
			try {
				o = other.getClass().newInstance();
				getUnits().add(o);
			} catch (IllegalAccessException e) {
			} catch (InstantiationException e) {
			}

		}
	}
}
